package com.hl.icd.utils;

import com.hl.icd.bean.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class JwtUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    private static Long ttl;

    static {
        ttl = 1000*60*60*24L;
    }

    public String createJWS(String subject, User user) {
        SecretKey secretKey = null;
        String secretKeyString = (String) redisTemplate.opsForValue().get("secretKey");

        if (secretKeyString == null) {
            secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
            String encode = parseSecretKeyToBase64(secretKey);
            redisTemplate.opsForValue().set("secretKey", encode, ttl, TimeUnit.MILLISECONDS);
        } else {
            secretKey = parseBase64ToSecretKey(secretKeyString);
        }

        Long timeMillis = System.currentTimeMillis();
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timeMillis);
        Date now = calendar.getTime();

        JwtBuilder builder = Jwts.builder()
                .setId(UUIDUtil.getUUID())
                .setSubject(subject)
                .setIssuedAt(now)
                .signWith(secretKey)
                .claim("id",user.getId())
                .claim("username", user.getUsername())
                .claim("nickname",user.getNickname())
                .claim("role",user.getRole())
                .setExpiration(new Date(System.currentTimeMillis()+ttl));
        return builder.compact();
    }

    /**
     * 解析JWT
     *
     * @param jws
     * @return
     */
    public Claims parseJWT(String jws) throws Exception{
        String secretKey = String.valueOf(redisTemplate.opsForValue().get("secretKey"));
        return Jwts.parserBuilder()
                .setSigningKey(secretKey)
                .build()
                .parseClaimsJws(jws)
                .getBody();
    }

    public String parseSecretKeyToBase64(SecretKey secretKey) {
        return Encoders.BASE64.encode(secretKey.getEncoded());
    }

    public SecretKey parseBase64ToSecretKey(String encode) {
        return Keys.hmacShaKeyFor(Decoders.BASE64.decode(encode));
    }

}
